home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / tee.zip / TEE.C < prev    next >
Text File  |  1994-07-10  |  6KB  |  225 lines

  1. /*
  2.  * Copyright (c) 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1988 Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)tee.c    5.11 (Berkeley) 5/6/91";
  42. #endif /* not lint */
  43.  
  44. #include <sys/types.h>
  45. #include <sys/stat.h>
  46. #include <fcntl.h>
  47. #include <signal.h>
  48. #include <stdio.h>
  49. #include <stdlib.h>
  50. #include <string.h>
  51. #include <io.h>
  52.  
  53. void    add(int, char *);
  54.  
  55. typedef    long    off_t;
  56. typedef    unsigned int u_int;
  57. typedef unsigned short u_short;
  58. typedef unsigned long u_long;
  59. #define STDOUT_FILENO 1
  60. #define STDIN_FILENO 0
  61. #define    DEFFILEMODE 0666
  62. #define index strchr
  63. #define rindex strrchr
  64.  
  65. int    opterr = 1,        /* if error message should be printed */
  66.     optind = 1,        /* index into parent argv vector */
  67.     optopt;            /* character checked for validity */
  68. char    *optarg;        /* argument associated with option */
  69.  
  70. #define    BADCH    (int)'?'
  71. #define    EMSG    ""
  72.  
  73. int
  74. getopt(int nargc, char * const *nargv, const char *ostr)
  75. {
  76.     static char *place = EMSG;        /* option letter processing */
  77.     register char *oli;            /* option letter list index */
  78.     char *p;
  79.  
  80.     if (!*place) {                /* update scanning pointer */
  81.         if (optind >= nargc || *(place = nargv[optind]) != '-') {
  82.             place = EMSG;
  83.             return(EOF);
  84.         }
  85.         if (place[1] && *++place == '-') {    /* found "--" */
  86.             ++optind;
  87.             place = EMSG;
  88.             return(EOF);
  89.         }
  90.     }                    /* option letter okay? */
  91.     if ((optopt = (int)*place++) == (int)':' ||
  92.         (oli = index(ostr, optopt)) == 0) {
  93.         /*
  94.          * if the user didn't specify '-' as an option,
  95.          * assume it means EOF.
  96.          */
  97.         if (optopt == (int)'-')
  98.             return(EOF);
  99.         if (!*place)
  100.             ++optind;
  101.         if (opterr) {
  102.             if ((p = rindex(*nargv, '/')) == 0)
  103.                 p = *nargv;
  104.             else
  105.                 ++p;
  106.             (void)fprintf(stderr, "%s: illegal option -- %c\n",
  107.                 p, optopt);
  108.         }
  109.         return(BADCH);
  110.     }
  111.     if (*++oli != ':') {            /* don't need argument */
  112.         optarg = NULL;
  113.         if (!*place)
  114.             ++optind;
  115.     }
  116.     else {                    /* need an argument */
  117.         if (*place)            /* no white space */
  118.             optarg = place;
  119.         else if (nargc <= ++optind) {    /* no arg */
  120.             place = EMSG;
  121.             if ((p = rindex(*nargv, '/')) == 0)
  122.                 p = *nargv;
  123.             else
  124.                 ++p;
  125.             if (opterr)
  126.                 (void)fprintf(stderr,
  127.                     "%s: option requires an argument -- %c\n",
  128.                     p, optopt);
  129.             return(BADCH);
  130.         }
  131.          else                /* white space */
  132.             optarg = nargv[optind];
  133.         place = EMSG;
  134.         ++optind;
  135.     }
  136.     return(optopt);                /* dump back option letter */
  137. }
  138.  
  139. typedef struct _list {
  140.     struct _list *next;
  141.     int fd;
  142.     char *name;
  143. } LIST;
  144. LIST *head;
  145.  
  146. main(argc, argv)
  147.     int argc;
  148.     char **argv;
  149. {
  150.     extern int errno, optind;
  151.     register LIST *p;
  152.     register int n, fd, rval, wval;
  153.     register char *bp;
  154.     int append, ch, exitval;
  155.     char *buf;
  156.     off_t lseek();
  157.  
  158.     append = 0;
  159.     while ((ch = getopt(argc, argv, "ai")) != EOF)
  160.         switch((char)ch) {
  161.         case 'a':
  162.             append = 1;
  163.             break;
  164.         case 'i':
  165.             (void)signal(SIGINT, SIG_IGN);
  166.             break;
  167.         case '?':
  168.         default:
  169.             (void)fprintf(stderr, "usage: tee [-ai] [file ...]\n");
  170.             exit(1);
  171.         }
  172.     argv += optind;
  173.     argc -= optind;
  174.  
  175.     if ((buf = malloc((u_int)8 * 1024)) == 0) {
  176.         (void)fprintf(stderr, "tee: out of space.\n");
  177.         exit(1);
  178.     }
  179.     add(STDOUT_FILENO, "stdout");
  180.     for (; *argv; ++argv)
  181.         if ((fd = open(*argv, append ? O_WRONLY|O_CREAT|O_APPEND :
  182.             O_WRONLY|O_CREAT|O_TRUNC, DEFFILEMODE)) < 0)
  183.             (void)fprintf(stderr, "tee: %s: %s.\n",
  184.                 *argv, strerror(errno));
  185.         else
  186.             add(fd, *argv);
  187.     exitval = 0;
  188.     while ((rval = read(STDIN_FILENO, buf, sizeof(buf))) > 0)
  189.         for (p = head; p; p = p->next) {
  190.             n = rval;
  191.             bp = buf;
  192.             do {
  193.                 if ((wval = write(p->fd, bp, n)) == -1) {
  194.                     (void)fprintf(stderr, "tee: %s: %s.\n",
  195.                         p->name, strerror(errno));
  196.                     exitval = 1;
  197.                     break;
  198.                 }
  199.                 bp += wval;
  200.             } while (n -= wval);
  201.         }
  202.     if (rval < 0) {
  203.         (void)fprintf(stderr, "tee: read: %s\n", strerror(errno));
  204.         exit(1);
  205.     }
  206.     exit(exitval);
  207.     return 1;
  208. }
  209.  
  210. void add(fd, name)
  211.     int fd;
  212.     char *name;
  213. {
  214.     LIST *p;
  215.  
  216.     if ((p = malloc((u_int)sizeof(LIST))) == 0) {
  217.         (void)fprintf(stderr, "tee: out of space.\n");
  218.         exit(1);
  219.     }
  220.     p->fd = fd;
  221.     p->name = name;
  222.     p->next = head;
  223.     head = p;
  224. }
  225.